﻿//-----------------------------------------------------------------------
// <copyright file="EditWorkerViewModel.cs" company="FER">
//     Copyright (c) All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace NMBP.View.ViewModel
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Messaging;

    using NMBP.DAL;
    using NMBP.Models;
    using NMBP.View.Validators;
    using NMBP.ViewModels.Dialogs;

    /// <summary>
    /// This class contains properties that the customer View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class EditWorkerViewModel : ViewModelBase
    {
        #region Binding Fields
        /// <summary>
        /// Gets or sets worker name
        /// </summary>
        private string name;

        /// <summary>
        /// Gets or sets worker surname
        /// </summary>
        private string surname;

        /// <summary>
        /// Gets or sets worker username
        /// </summary>
        private string username;

        /// <summary>
        /// Gets or sets worker password
        /// </summary>
        private string password;

        /// <summary>
        /// Gets or sets worker contact
        /// </summary>
        private string contact;

        /// <summary>
        /// Gets or sets worker sallary
        /// </summary>
        private float sallary;

        /// <summary>
        /// Gets or sets worker VpnNumber
        /// </summary>
        private string vpnNumber;

        /// <summary>
        /// Gets or sets worker department
        /// </summary>
        private Department department;

        /// <summary>
        /// Gets or sets the list of available departments
        /// </summary>
        private List<Department> availableDepartments;

        /// <summary>
        /// Gets or sets whether the worker is a manager or not
        /// </summary>
        private bool isManager;

        /// <summary>
        /// Gets or sets whether the worker has admin rights or not
        /// </summary>
        private bool isAdmin;

        /// <summary>
        /// Action raised when worker view model needs to be initialized
        /// </summary>
        private Action<Worker> initWorkerViewModel;

        /// <summary>
        /// Gets or sets selected worker
        /// </summary>
        private Worker selectedWorker;

        /// <summary>
        /// Gets or sets list of all workers
        /// </summary>
        private ObservableCollection<Worker> allWorkers;
        #endregion

        /// <summary>
        /// Gets or sets the received worker
        /// </summary>
        private Worker recievedWorker;

        private bool isUsernameEnabled;

        /// <summary>
        /// Initializes a new instance of the EditWorkerViewModel class
        /// </summary>
        public EditWorkerViewModel()
        {
            this.initWorkerViewModel = new Action<Worker>(this.InitializeViewModel);
            Messenger.Default.Register<Worker>(this, "InitializeEditWorker", this.initWorkerViewModel);

            this.SaveEditWorker = new RelayCommand(
                () =>
                {
                    var newWorker = new Worker();
                    newWorker.Name = this.Name;
                    newWorker.Surname = this.Surname;
                    newWorker.Username = this.Username;
                    newWorker.Password = this.Password;
                    newWorker.Contact = this.Contact;
                    newWorker.VpnNumber = this.VpnNumber;
                    newWorker.Sallary = this.Sallary;
                    newWorker.Department = this.Department;

                    newWorker.IsAdmin = this.IsAdmin;
                    newWorker.IsManager = this.IsManager;
                    if (this.IsManager)
                    {
                        newWorker.Department.ManagerUsername = newWorker.Username;
                    }

                    if (newWorker.Department.Employees == null)
                    {
                        newWorker.Department.Employees = new List<string>();
                    }
                    newWorker.Department.Employees.Add(newWorker.Username);

                    if (!WorkerValidator.ValidateWorker(newWorker))
                    {
                        this.DialogService.ShowMessage("Neispravni parametri za radnika. Ne spremam.", MessageType.ERROR);
                        return;
                    }

                    this.DbFacade.SaveWorker(newWorker);

                    Messenger.Default.Send(this.recievedWorker, "CloseEditWorkerWindow");
                });


            this.CancelEditWorker = new RelayCommand(
                () =>
                {
                    Messenger.Default.Send(this.recievedWorker, "CloseEditWorkerWindow");
                });
        }

        #region Bindable Properties
        /// <summary>
        /// Gets or sets dbFacade
        /// </summary>
        public IDbFacade DbFacade { get; set; }

        /// <summary>
        /// Gets or sets dialog service
        /// </summary>
        public IDialogService DialogService { get; set; }

        /// <summary>
        /// Gets or sets worker name
        /// </summary>
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                this.name = value;
                this.RaisePropertyChanged("Name");
            }
        }

        /// <summary>
        /// Gets or sets worker surname
        /// </summary>
        public string Surname
        {
            get
            {
                return this.surname;
            }

            set
            {
                this.surname = value;
                this.RaisePropertyChanged("Surname");
            }
        }

        /// <summary>
        /// Gets or sets worker username
        /// </summary>
        public string Username
        {
            get
            {
                return this.username;
            }

            set
            {
                this.username = value;
                this.RaisePropertyChanged("Username");
            }
        }

        /// <summary>
        /// Gets or sets worker password
        /// </summary>
        public string Password
        {
            get
            {
                return this.password;
            }

            set
            {
                this.password = value;
                this.RaisePropertyChanged("Password");
            }
        }

        /// <summary>
        /// Gets or sets worker contact
        /// </summary>
        public string Contact
        {
            get
            {
                return this.contact;
            }

            set
            {
                this.contact = value;
                this.RaisePropertyChanged("Contact");
            }
        }

        /// <summary>
        /// Gets or sets worker sallary
        /// </summary>
        public float Sallary
        {
            get
            {
                return this.sallary;
            }

            set
            {
                this.sallary = value;
                this.RaisePropertyChanged("Sallary");
            }
        }

        /// <summary>
        /// Gets or sets worker VpnNumber
        /// </summary>
        public string VpnNumber
        {
            get
            {
                return this.vpnNumber;
            }

            set
            {
                this.vpnNumber = value;
                this.RaisePropertyChanged("VpnNumber");
            }
        }

        /// <summary>
        /// Gets or sets worker department
        /// </summary>
        public Department Department
        {
            get
            {
                return this.department;
            }

            set
            {
                this.department = value;
                this.RaisePropertyChanged("Department");
            }
        }

        /// <summary>
        /// Gets or sets the list of available departments
        /// </summary>
        public List<Department> AvailableDepartments
        {
            get
            {
                return this.availableDepartments;
            }

            set
            {
                this.availableDepartments = value;
                this.RaisePropertyChanged("AvailableDepartments");
            }
        }

        /// <summary>
        /// Gets or sets whether the worker is a manager or not
        /// </summary>
        public bool IsManager
        {
            get
            {
                return this.isManager;
            }

            set
            {
                this.isManager = value;
                this.RaisePropertyChanged("IsManager");
            }
        }

        /// <summary>
        /// Gets or sets whether the worker has admin rights or not
        /// </summary>
        public bool IsAdmin
        {
            get
            {
                return this.isAdmin;
            }

            set
            {
                this.isAdmin = value;
                this.RaisePropertyChanged("IsAdmin");
            }
        }

        /// <summary>
        /// Gets or sets list of all workers
        /// </summary>
        public ObservableCollection<Worker> AllWorkers
        {
            get
            {
                return this.allWorkers;
            }

            set
            {
                this.allWorkers = value;
                this.RaisePropertyChanged("AllWorkers");
            }
        }

        /// <summary>
        /// Gets or sets selected worker
        /// </summary>
        public Worker SelectedWorker
        {
            get
            {
                return this.selectedWorker;
            }

            set
            {
                this.selectedWorker = value;
                if (value != null)
                {
                    if (value.Username == "-- odaberite --")
                    {
                        this.IsUsernameEnabled = true;
                        this.ClearAllFields();
                    }
                    else
                    {
                        this.IsUsernameEnabled = false;
                        this.LoadAllValues();
                    }
                }
                this.RaisePropertyChanged("SelectedWorker");
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether enabled username
        /// </summary>
        public bool IsUsernameEnabled
        {
            get
            {
                return this.isUsernameEnabled;
            }

            set
            {
                this.isUsernameEnabled = value;
                this.RaisePropertyChanged("IsUsernameEnabled");
            }
        }
        #endregion

        #region Bindable commands
        /// <summary>
        /// Gets the command raised when save edit worker button is clicked
        /// </summary>
        public RelayCommand SaveEditWorker { get; private set; }

        /// <summary>
        /// Gets the command raised when cancel edit worker button is clicked
        /// </summary>
        public RelayCommand CancelEditWorker { get; private set; }

        #endregion

        /// <summary>
        /// Initializes view model
        /// </summary>
        /// <param name="worker">Worker to initialize view model</param>
        private void InitializeViewModel(Worker worker)
        {
            if (this.DbFacade == null)
            {
                this.DbFacade = new DbFacade();
            }

            this.recievedWorker = worker;
            this.AvailableDepartments = this.DbFacade.GetDepartments();
            this.DialogService = new DialogService();
            this.AllWorkers = new ObservableCollection<Worker>();
            this.AllWorkers.Insert(0, new Worker { Username = "-- odaberite --"});
            var workers = this.DbFacade.GetWorkers();
            foreach (var worker1 in workers)
            {
                this.AllWorkers.Add(worker1);
            }
            this.SelectedWorker = this.AllWorkers[0];
            this.ClearAllFields();
        }

        /// <summary>
        /// Loads values for selected customer
        /// </summary>
        private void LoadAllValues()
        {
            this.Name = this.SelectedWorker.Name;
            this.Surname = this.SelectedWorker.Surname;
            this.Contact = this.SelectedWorker.Contact;
            this.Username = this.SelectedWorker.Username;
            this.Password = this.SelectedWorker.Password;
            this.VpnNumber = this.SelectedWorker.VpnNumber;
            this.Sallary = this.SelectedWorker.Sallary;
            if (this.SelectedWorker.Department != null)
            {
                this.Department = this.AvailableDepartments.FirstOrDefault(d => d.Name == this.SelectedWorker.Department.Name);
                if (this.Department == null)
                {
                    this.Department = this.AvailableDepartments[0];
                }
                else
                {
                    var indexOfDepartment = this.AvailableDepartments.IndexOf(this.Department);
                    this.Department = this.AvailableDepartments[indexOfDepartment];
                }
            }

            this.IsAdmin = this.SelectedWorker.IsAdmin;
            this.IsManager = this.SelectedWorker.IsManager;
        }

        /// <summary>
        /// Clears all fields
        /// </summary>
        private void ClearAllFields()
        {
            this.Name = string.Empty;
            this.Surname = string.Empty;
            this.Contact = string.Empty;
            this.Username = string.Empty;
            this.Password = string.Empty;
            this.VpnNumber = string.Empty;
            this.Sallary = 0;
            this.Department = this.AvailableDepartments[0];
            this.IsAdmin = false;
            this.IsManager = false;
        }
    }
}
